package cn.b.sky.message.service.impl;

import cn.b.sky.common.exception.ImeException;
import cn.b.sky.common.utils.SpringBeanUtil;
import cn.b.sky.message.dao.MessageDao;
import cn.b.sky.message.model.*;
import cn.b.sky.message.model.condition.InstantMessageCondition;
import cn.b.sky.message.model.condition.MessageConfigCondition;
import cn.b.sky.message.service.MessageSenderService;
import cn.b.sky.message.service.MessageService;
import cn.b.sky.message.service.SmartDeviceMessageSenderService;
import cn.b.sky.user.dao.UserDao;
import cn.b.sky.user.service.OrganizationService;
import cn.b.sky.user.service.RoleService;
import cn.b.sky.user.service.model.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 
 * <strong>Title : MessageServiceImpl.java<br>
 * </strong> <strong>Package : cn.b.sky..template.message.service.impl<br>
 * </strong> <strong>Description : </strong>消息业务实现类<br>
 * <strong>Create on : 2015-9-18 下午01:34:09<br>
 * </strong>
 * <p>
 * 
 * @author dapeng.li<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 *          <strong>修改历史:</strong><br>
 *          修改人 | 修改日期 | 修改描述<br>
 *          -------------------------------------------<br>
 * <br>
 * <br>
 */
@Service("messageService")
public class MessageServiceImpl implements MessageService {
  @Resource
  private MessageDao messageDao;

  @Resource
  private UserDao userDao;

  @Resource
  MessageSenderService emailMessageSenderImpl;

  @Resource
  MessageSenderService instantMessageSenderImpl;

  @Resource
  MessageSenderService shortMessageSenderImpl;

  @Resource
  RoleService roleService;

  @Resource
  OrganizationService organizationService;

  // @Resource
  // private UserProfileService userProfileService;

  @Override
  public void sendMessage(String siteCode, String messageCode, Object[] params) {
    // 获得消息配置
    MessageConfigInfo info = selectMessageConfig(siteCode, messageCode);
    if (info == null) {
      throw ImeException.newException("messageNotExist.M");
    }
    // 获得消息内容
    MessageContentInfo contentInfo = new MessageContentInfo();
    contentInfo.setMessageCode(messageCode);
    contentInfo.setSiteCode(siteCode);
    List<MessageContentInfo> contents = messageDao.selectMessageContent(contentInfo);

    List<UserInfo> users = getUsers(siteCode, messageCode);
    for (UserInfo userInfo : users) {
      String message = "";
      for (MessageContentInfo c : contents) {
        if (c.getLanguageCode().equals(userInfo.getLanguageCode())) {
          message = c.getMessageContent();
          break;
        }
      }
      if (StringUtils.isEmpty(message)) {
        message = info.getMessageContent();
      }
      if (params != null) {
        for (int i = 0; i < params.length; i++) {
          message = message.replace("${" + i + "}", params[i].toString());
        }
      }
      message = message.replaceAll("\\$\\{\\d*\\}", "");
      sentMessage(info, messageCode, message, siteCode, userInfo);
    }

  }

  /**
   * 
   * <strong>Title : getUsers<br></strong>
   * <strong>Description : </strong>获得所有消息接收者<br> 
   * <strong>Create on : 2016年6月27日 下午5:30:27<br></strong>
   * <p>
   * @param siteCode
   * @param messageCode
   * @return
   * List<UserInfo>
   * @throws 
   * @author dapeng.li<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  private List<UserInfo> getUsers(String siteCode, String messageCode) {
    List<UserInfo> users = new ArrayList<UserInfo>();
    List<MessageReceiverInfo> receivers = selectMessageReceiver(siteCode, messageCode);
    // 获得所有消息接收者
    for (MessageReceiverInfo rinfo : receivers) {
      if ("U".equals(rinfo.getReceiverType())) {
        UserInfo user = new UserInfo();
        user.setUserCode(rinfo.getReceiverCode());
        if (!IsExistUser(user, users)) {
          user = userDao.selectUser(siteCode, rinfo.getReceiverCode());
          if (!"1".equals(user.getLockFlag())) {
            users.add(user);
          }
        }
      } else if ("R".equals(rinfo.getReceiverType())) {
        List<UserInfo> userList = roleService.selectUserByRole(siteCode, rinfo.getReceiverCode());
        for (UserInfo userInfo : userList) {
          if (!IsExistUser(userInfo, users) && !"1".equals(userInfo.getLockFlag())) {
            users.add(userInfo);
          }
        }

      } else if ("O".equals(rinfo.getReceiverType())) {
        List<UserInfo> userList = organizationService.selectUsersByOrganization(siteCode, rinfo.getReceiverCode());
        for (UserInfo userInfo : userList) {
          if (!IsExistUser(userInfo, users) && !"1".equals(userInfo.getLockFlag())) {
            users.add(userInfo);
          }
        }
      }
    }
    return users;
  }

  /**
   * 判断用户列表中是否已经存在该用户
   * 
   * @param user
   * @param users
   * @return
   */
  boolean IsExistUser(UserInfo user, List<UserInfo> users) {
    boolean isExist = false;
    for (UserInfo userInfo : users) {
      if (userInfo.getUserCode().equals(user.getUserCode())) {
        isExist = true;
        break;
      }
    }
    return isExist;
  }

  /**
   * 直接发送消息，不用事先配置消息代码
   */
  @Override
  public void sentMessage(String siteCode, String message, MessageUser messageUser) {
    if (messageUser != null) {
      List<UserInfo> users = getUsersForOnlyUseTemplate(siteCode, messageUser);
      // 发送即时消息
      for (UserInfo userInfo : users) {
        instantMessageSenderImpl.sentMessage("", message, siteCode, userInfo.getUserCode());
      }
    }

  }

  /**
   * 根据消息代码查询消息配置
   */
  @Override
  public MessageConfigInfo selectMessageConfig(String siteCode, String messageCode) {

    return messageDao.selectMessageConfig(siteCode, messageCode);

  }

  /**
   * 新增消息配置
   */
  @Override
  public void insertMessageConfig(MessageConfigInfo messageConfigInfo) {
    messageDao.insertMessageConfig(messageConfigInfo);
    for (MessageContentInfo cinfo : messageConfigInfo.getContents()) {
      messageDao.insertMessageContent(cinfo);
    }
    List<MessageReceiverInfo> receivers = messageConfigInfo.getReceivers();
    for (MessageReceiverInfo rinfo : receivers) {
      messageDao.insertMessageReceiver(rinfo);
    }

  }

  /**
   * 更新消息配置
   */
  @Override
  public void updateMessageConfig(MessageConfigInfo messageConfigInfo) {

    messageDao.updateMessageConfig(messageConfigInfo);
    messageDao.deleteMessageContent(messageConfigInfo.getSiteCode(), messageConfigInfo.getMessageCode());
    for (MessageContentInfo cinfo : messageConfigInfo.getContents()) {
      messageDao.insertMessageContent(cinfo);
    }
    messageDao.deleteMessageReceiver(messageConfigInfo.getSiteCode(), messageConfigInfo.getMessageCode());
    List<MessageReceiverInfo> receivers = messageConfigInfo.getReceivers();
    for (MessageReceiverInfo rinfo : receivers) {
      messageDao.insertMessageReceiver(rinfo);
    }

  }

  /**
   * 删除消息配置
   */
  @Override
  public void deleteMessageConfig(String siteCode, String messageCode) {
    messageDao.deleteMessageReceiver(siteCode, messageCode);
    messageDao.deleteMessageContent(siteCode, messageCode);
    messageDao.deleteMessageConfig(siteCode, messageCode);

  }

  /**
   * 标记消息为已读状态
   */
  @Override
  public void doMarkAsRead(long messageId) {
    messageDao.doMarkAsRead(messageId);

  }

  /**
   * 查询是否有未读消息
   */
  @Override
  public int selectUnReadMessageCount(String siteCode, String userCode) {

    return messageDao.selectUnReadMessageCount(siteCode, userCode);

  }

  @Override
  public List<MessageContentInfo> selectAllLanguage() {

    return messageDao.selectAllLanguage();

  }

  @Override
  public List<MessageContentInfo> selectContentListByMessageCode(String siteCode, String messageCode) {

    return messageDao.selectContentListByMessageCode(siteCode, messageCode);

  }

  @Override
  public List<InstantMessageInfo> selectUnReadMeaage(InstantMessageCondition instantMessageCondition) {
    return messageDao.selectUnReadMeaage(instantMessageCondition);
  }

  @Override
  public InstantMessageInfo selectInstantMessageById(long id) {
    return messageDao.selectInstantMessageById(id);
  }

  @Override
  public List<InstantMessageInfo> selectHisInstantMessageList(InstantMessageCondition instantMessageCondition) {
    return messageDao.selectHisInstantMessageList(instantMessageCondition);
  }

  @Override
  public int selectHisInstantMessageCount(InstantMessageCondition instantMessageCondition) {
    return messageDao.selectHisInstantMessageCount(instantMessageCondition);
  }

  @Override
  public List<MessageConfigInfo> selectMessageConfigList(MessageConfigCondition messageConfigCondition) {
    return messageDao.selectMessageConfigList(messageConfigCondition);
  }

  @Override
  public int selectMessageConfigCount(MessageConfigCondition messageConfigCondition) {
    return messageDao.selectMessageConfigCount(messageConfigCondition);
  }

  @Override
  public List<MessageReceiverInfo> selectMessageReceiver(String siteCode, String messageCode) {
    return messageDao.selectMessageReceiver(siteCode, messageCode);
  }

  @Override
  public void sendMessageOnlyUseTemplate(String siteCode, String messageCode, Object[] params, MessageUser messageUser) {
    // 获得消息配置
    MessageConfigInfo info = selectMessageConfig(siteCode, messageCode);
    if (info == null) {
      throw ImeException.newException("messageNotExist.M");
    }
    // 获得消息内容
    MessageContentInfo contentInfo = new MessageContentInfo();
    contentInfo.setMessageCode(messageCode);
    contentInfo.setSiteCode(siteCode);
    List<MessageContentInfo> contents = messageDao.selectMessageContent(contentInfo);

    if (messageUser != null) {
      List<UserInfo> users = getUsersForOnlyUseTemplate(siteCode, messageUser);
      // 发送即时消息
      for (UserInfo userInfo : users) {
        String message = "";
        for (MessageContentInfo c : contents) {
          if (c.getLanguageCode().equals(userInfo.getLanguageCode())) {
            message = c.getMessageContent();
            break;
          }
        }
        if (StringUtils.isEmpty(message)) {
          message = info.getMessageContent();
        }
        if (params != null) {
          for (int i = 0; i < params.length; i++) {
            message = message.replace("${" + i + "}", params[i].toString());
          }
        }
        message = message.replaceAll("\\$\\{\\d*\\}", "");
        sentMessage(info, messageCode, message, siteCode, userInfo);
      }
    }
  }

  private List<UserInfo> getUsersForOnlyUseTemplate(String siteCode, MessageUser messageUser) {
    List<UserInfo> users = new ArrayList<UserInfo>();

    if (messageUser.getUserList() != null) {
      for (String ucode : messageUser.getUserList()) {
        UserInfo user = new UserInfo();
        user.setUserCode(ucode);
        if (!IsExistUser(user, users)) {
          user = userDao.selectUser(siteCode, user.getUserCode());
          if (user != null && !"1".equals(user.getLockFlag())) {
            users.add(user);
          }
        }
      }
    }
    if (messageUser.getRoleList() != null) {
      for (String roleCode : messageUser.getRoleList()) {
        List<UserInfo> userList = roleService.selectUserByRole(siteCode, roleCode);
        for (UserInfo userInfo : userList) {
          if (!IsExistUser(userInfo, users) && !"1".equals(userInfo.getLockFlag())) {
            users.add(userInfo);
          }
        }
      }
    }
    if (messageUser.getOrgList() != null) {
      for (String oCode : messageUser.getOrgList()) {
        List<UserInfo> userList = organizationService.selectUsersByOrganization(siteCode, oCode);
        for (UserInfo userInfo : userList) {
          if (!IsExistUser(userInfo, users) && !"1".equals(userInfo.getLockFlag())) {
            users.add(userInfo);
          }
        }
      }
    }
    return users;
  }

  @Override
  public void sendMessageToGivenUser(String siteCode, String messageCode, MessageUser messageUser,
      Map<String, String> params) {
    // 获得消息配置
    MessageConfigInfo info = selectMessageConfig(siteCode, messageCode);
    if (info == null) {
      throw ImeException.newException("messageNotExist.M");
    }
    // 获得消息内容
    MessageContentInfo contentInfo = new MessageContentInfo();
    contentInfo.setMessageCode(messageCode);
    contentInfo.setSiteCode(siteCode);
    List<MessageContentInfo> contents = messageDao.selectMessageContent(contentInfo);
    List<UserInfo> users = getUsersForOnlyUseTemplate(siteCode, messageUser);

    for (UserInfo userInfo : users) {
      String message = "";
      for (MessageContentInfo c : contents) {
        if (c.getLanguageCode().equals(userInfo.getLanguageCode())) {
          message = c.getMessageContent();
          break;
        }
      }
      if (StringUtils.isEmpty(message)) {
        message = info.getMessageContent();
      }
      if (params != null) {
        for (String key : params.keySet()) {
          message = message.replace("${" + key + "}", params.get(key));
        }
      }
      message = message.replaceAll("\\$\\{\\d*\\}", "");
      
      sentMessage(info, messageCode, message, siteCode, userInfo);
    }
  }

  private void sentMessage(MessageConfigInfo info, String messageCode, String message, String siteCode, UserInfo userInfo) {
 // 根据接收方式发送消息
    if (info.getEmailMessageFlag() == 1 && !StringUtils.isEmpty(userInfo.getEmail())) {
      // 发送邮件
      emailMessageSenderImpl.sentMessage(messageCode, message, siteCode, userInfo.getUserCode());
    }
    if (info.getInstantMessageFlag() == 1) {
      // 发送即时消息
      instantMessageSenderImpl.sentMessage(messageCode, message, siteCode, userInfo.getUserCode());
    }
    if (info.getShortMessageFlag() == 1) {
      // 发送手机短信
      shortMessageSenderImpl.sentMessage(messageCode, message, siteCode, userInfo.getUserCode());
    }
    if (info.getWechatMessageFlag() == 1 || info.getSmartWatchMessageFlag() == 1) {
      SmartDeviceMessageSenderService smartDeviceMessageSenderService = (SmartDeviceMessageSenderService) SpringBeanUtil
          .getBean("smartDeviceMessageSenderService");

      if (info.getWechatMessageFlag() == 1) {
        //发送微信消息
        smartDeviceMessageSenderService.sentWeChatMessage(messageCode, messageCode, siteCode, userInfo.getUserCode());
      }
      if (info.getSmartWatchMessageFlag() == 1) {
        //发送智能手表消息
        smartDeviceMessageSenderService.sentSmartWatchMessage(messageCode, messageCode, siteCode,
            userInfo.getUserCode());
      }
    }
    
  }

}
